Skip to content

feat(executor): introduce workflow executor#1564

Merged
Scra3 merged 216 commits into
mainfrom
feat/prd-214-server-step-mapper
Jun 9, 2026
Merged

feat(executor): introduce workflow executor#1564
Scra3 merged 216 commits into
mainfrom
feat/prd-214-server-step-mapper

Conversation

@Scra3

@Scra3 Scra3 commented Apr 20, 2026

Copy link
Copy Markdown
Member

MAIN BRANCH TO INTRODUCE WORKFLOW EXECUTOR.

image

Note

Add workflow executor package with step executors, HTTP API, and CLI

  • Introduces a new @forestadmin/workflow-executor package that runs Forest Admin workflow steps (condition, read-record, update-record, trigger-action, load-related-record, mcp, guidance) against agent data with AI assistance.
  • Adds a Runner with start/stop lifecycle, polling, in-flight run tracking, and graceful drain-on-shutdown; step execution is handled by per-type executors derived from BaseStepExecutor with timeout enforcement and idempotency checks.
  • Exposes a Koa HTTP server (ExecutorHttpServer) with JWT auth, /health, GET /runs/:runId, and POST /runs/:runId/trigger endpoints; the agent gains a workflowExecutorUrl option and a proxy route (WorkflowExecutorProxyRoute) that forwards /_internal/workflow-executions/* to the executor.
  • Persistence uses either a SQLite/Postgres-backed DatabaseStore (with Umzug migrations) or an InMemoryStore; activity log transitions are tracked and drained via ActivityLogDrainer.
  • Extends @forestadmin/ai-proxy with AiClient, createBaseChatModel, mcpServerId propagation across RemoteTool subclasses, and validateAiConfigurations; fixes QuerySerializer.formatFields to emit comma-separated strings instead of arrays to prevent field loss in Rack-based agents.
  • Risk: the QuerySerializer change alters serialized query parameter format for field projections, which may affect any consumers relying on the previous array format.

Macroscope summarized 6aa8faa.

matthv and others added 30 commits March 17, 2026 15:00
…premature deps, add smoke test

- Rewrite CLAUDE.md with project overview and architecture principles, remove changelog
- Remove unused dependencies (ai-proxy, sequelize, zod) per YAGNI
- Add smoke test so CI passes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… document system architecture

- Lint now covers src and test directories
- Replace require() with import, use stronger assertion (toHaveLength)
- Add System Architecture section describing Front/Orchestrator/Executor/Agent
- Mark Architecture Principles as planned (not yet implemented)
- Remove redundant test/.gitkeep
- Make index.ts a valid module with export {}

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…erver (#1504)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: alban bertolini <albanb@forestadmin.com>
…ain (#1512)

Co-authored-by: alban bertolini <albanb@forestadmin.com>
- Remove McpClient.tools property, loadTools() returns local array
- Rename closeConnections() → dispose()
- Rename testConnections() → checkConnection()
- Add McpServers type export
- Rename mcpServerConfigs → toolConfigs in create-ai-provider
- Update all tests accordingly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eability

Add sourceId to McpToolRef so that persisted execution data (pendingData,
executionParams) tracks which MCP server provided the tool. This fixes
tool lookup on re-entry (confirmation flow) when multiple servers expose
tools with the same name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… collection schema

- Replace non-null assertion with explicit McpToolNotFoundError when AI
  selects a tool name that doesn't match any available tool
- Resolve related collection name from parent schema before looking up
  the related schema in cache, fixing cases where relation name differs
  from target collection name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge main into feature branch, resolve conflicts by taking main's
versions of router.ts, create-ai-provider.ts and their tests.
Remove deleted mcp-config-checker.ts. Bump workflow-executor internal
deps to match main.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
nbouliol and others added 20 commits June 3, 2026 13:39
…ing provider errors [PRD-409] (#1609)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: alban bertolini <albanb@forestadmin.com>
…s (PRD-432) (#1620)

The executor mints the JWT it sends to the agent from StepUser (camelCase).
Ruby/Python agents splat JWT claims straight into Caller.new, which requires
snake_case kwargs (first_name, last_name, rendering_id, permission_level), so
the call failed with a 500 ArgumentError. The TS agent reads camelCase. There
is no single canonical casing, so emit both: the Ruby Caller absorbs the extra
camelCase keys via **_extra_args and the TS agent ignores the snake_case ones.

fixes PRD-432

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…e [PRD-430] (#1621)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tring (PRD-437) (#1622)

* fix(agent-client): serialize fields[] projection as comma-separated string (PRD-437)

QuerySerializer.formatFields returned an array for the sparse fieldset
projection (e.g. { 'fields[Customer]': ['first_name','last_name','email'] }).
superagent serializes arrays via qs.stringify(obj, { indices: false }) as
repeated keys without brackets:

  fields[Customer]=first_name&fields[Customer]=last_name&fields[Customer]=email

Rack-based (Ruby) agents collapse duplicate scalar keys to the LAST value, so
parse_projection (which does fields.split(',')) only ever saw the last field.
A getData/read-record reading first_name, last_name, email returned only email
(plus the primary key). The TS agent was unaffected by luck: it does
fields.toString().split(','), and Array.toString() rejoins with commas.

Join each projection into a single comma-separated value (JSON:API sparse
fieldset standard), which both Ruby (split) and Node agents parse correctly.
Also fixes the same class of issue for update-record and getRelatedData, which
share this serialization. Sibling of PRD-273 #8 (filter operator casing).

Update the mcp-server consumer tests that asserted the old array shape, and
tighten the field assertions to token-based matching (no substring matches).

fixes PRD-437

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…#1623)

fix(workflow-executor): drop dead-branch steps from context (PRD-433)

Revising a step forks the run history: the orchestrator stamps the pivot
card revised and the downstream branch cancelled, then re-appends the
still-valid steps as clones carrying originalStepIndex. The executor read
that history branch-blind, so re-executed steps inherited stale AI context
and the record pool offered records loaded by superseded steps (e.g.
revising "Load store" proposed loading from the dead branch's owner).

previousSteps now mirrors the orchestrator's own live-path filter
(!revised && !cancelled). resolveStepExecution then resolves a step's
RunStore execution own-index-first: a step the executor ran has its entry
at its own stepIndex; a revision clone — which never ran — falls back to
originalStepIndex, where the copied step's record lives (mirroring the
frontend's carry-forward, resolved on read rather than copied). The
fallback is gated on a non-error outcome, so a re-executed step that
produced no record (failed / skipped / handled manually) never resurfaces
its superseded original's record. Records are never keyed by stepName:
LinkTo loops make names non-unique on the live path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: alban bertolini <albanb@forestadmin.com>
…d route [PRD-450] (#1629)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t [PRD-450] (#1636)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: alban bertolini <albanb@forestadmin.com>
…tep-mapper

# Conflicts:
#	package.json
#	yarn.lock
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
yarn no longer nests @ForestAdmin packages under packages/*/node_modules,
so the rm -rf workaround is a no-op.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Scra3 Scra3 changed the title feat: connect orchestrator and frontend feat(executor): introduce workflow executor Jun 9, 2026
@Scra3 Scra3 merged commit 1545069 into main Jun 9, 2026
45 of 84 checks passed
forest-bot added a commit that referenced this pull request Jun 9, 2026
forest-bot added a commit that referenced this pull request Jun 9, 2026
# @forestadmin/forestadmin-client [1.40.0](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/forestadmin-client@1.39.9...@forestadmin/forestadmin-client@1.40.0) (2026-06-09)

### Features

* **executor:** introduce workflow executor ([#1564](#1564)) ([1545069](1545069))

### Dependencies

* **@forestadmin/ai-proxy:** upgraded to 1.11.0
forest-bot added a commit that referenced this pull request Jun 9, 2026
# @forestadmin/agent-client [1.6.0](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/agent-client@1.5.10...@forestadmin/agent-client@1.6.0) (2026-06-09)

### Features

* **executor:** introduce workflow executor ([#1564](#1564)) ([1545069](1545069))

### Dependencies

* **@forestadmin/forestadmin-client:** upgraded to 1.40.0
forest-bot added a commit that referenced this pull request Jun 9, 2026
# @forestadmin/mcp-server [1.12.0](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/mcp-server@1.11.11...@forestadmin/mcp-server@1.12.0) (2026-06-09)

### Features

* **executor:** introduce workflow executor ([#1564](#1564)) ([1545069](1545069))

### Dependencies

* **@forestadmin/agent-client:** upgraded to 1.6.0
* **@forestadmin/forestadmin-client:** upgraded to 1.40.0
forest-bot added a commit that referenced this pull request Jun 9, 2026
# @forestadmin/agent [1.79.0](https://github.com/ForestAdmin/agent-nodejs/compare/@forestadmin/agent@1.78.13...@forestadmin/agent@1.79.0) (2026-06-09)

### Features

* **executor:** introduce workflow executor ([#1564](#1564)) ([1545069](1545069))

### Dependencies

* **@forestadmin/forestadmin-client:** upgraded to 1.40.0
* **@forestadmin/mcp-server:** upgraded to 1.12.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants